home *** CD-ROM | disk | FTP | other *** search
/ United Public Domain Gold 2 / United Public Domain Gold 2.iso / music_utilities / pt030.dms / pt030.adf / Less / Src / signal.c < prev    next >
C/C++ Source or Header  |  1987-06-15  |  4KB  |  197 lines

  1. /*
  2.  * Routines dealing with signals.
  3.  *
  4.  * A signal usually merely causes a bit to be set in the "signals" word.
  5.  * At some convenient time, the mainline code checks to see if any
  6.  * signals need processing by calling psignal().
  7.  * An exception is made if we are reading from the keyboard when the
  8.  * signal is received.  Some operating systems will simply call the
  9.  * signal handler and NOT return from the read (with EINTR).
  10.  * To handle this case, we service the interrupt directly from
  11.  * the handler if we are reading from the keyboard.
  12.  */
  13.  
  14. #include "less.h"
  15. #include <signal.h>
  16. #include <setjmp.h>
  17.  
  18. /*
  19.  * The type of signal handler functions.
  20.  * Usually int, although it should be void.
  21.  */
  22. typedef    int        HANDLER;
  23.  
  24. /*
  25.  * "sigs" contains bits indicating signals which need to be processed.
  26.  */
  27. public int sigs;
  28. #define    S_INTERRUPT    01
  29. #ifdef SIGTSTP
  30. #define    S_STOP        02
  31. #endif
  32.  
  33. extern int reading;
  34. extern int sc_width, sc_height;
  35. extern char *first_cmd;
  36. extern jmp_buf main_loop;
  37.  
  38. /*
  39.  * Interrupt signal handler.
  40.  */
  41.     static HANDLER
  42. interrupt()
  43. {
  44. #ifndef AMIGA
  45.     SIGNAL(SIGINT, interrupt);
  46.     sigs |= S_INTERRUPT;
  47.     if (reading)
  48.         psignals();
  49. #endif
  50. }
  51.  
  52. #ifdef SIGTSTP
  53. /*
  54.  * "Stop" (^Z) signal handler.
  55.  */
  56.     static HANDLER
  57. stop()
  58. {
  59.     SIGNAL(SIGTSTP, stop);
  60.     sigs |= S_STOP;
  61.     if (reading)
  62.         psignals();
  63. }
  64. #endif
  65.  
  66. #ifdef SIGWINCH
  67. /*
  68.  * "Window" change handler
  69.  */
  70. winch()
  71. {
  72.     SIGNAL(SIGWINCH, winch);
  73.     sigs |= S_WINCH;
  74.     if (reading)
  75.         psignals();
  76. }
  77. #else
  78. #ifdef SIGWIND
  79. /*
  80.  * "Window" change handler
  81.  */
  82. winch()
  83. {
  84.     SIGNAL(SIGWIND, winch);
  85.     sigs |= S_WINCH;
  86.     if (reading)
  87.         psignals();
  88. }
  89. #endif
  90. #endif
  91.  
  92. /*
  93.  * Set up the signal handlers.
  94.  */
  95.     public void
  96. init_signals()
  97. {
  98. #ifndef AMIGA
  99.     (void) SIGNAL(SIGINT, interrupt);
  100. #ifdef SIGTSTP
  101.     (void) SIGNAL(SIGTSTP, stop);
  102. #endif
  103. #ifdef SIGWINCH
  104.     (void) SIGNAL(SIGWINCH, winch);
  105. #else
  106. #ifdef SIGWIND
  107.     (void) SIGNAL(SIGWIND, winch);
  108. #endif
  109. #endif
  110. #endif
  111. }
  112.  
  113. /*
  114.  * Process any signals we have recieved.
  115.  * A received signal cause a bit to be set in "sigs".
  116.  */
  117.     public void 
  118. psignals()
  119. {
  120. #ifndef AMIGA
  121.     register int tsignals;
  122.  
  123.     tsignals = sigs;
  124.     sigs = 0;
  125.     if (tsignals == 0)
  126.         return;
  127.  
  128.     dropout();        /* Discard any buffered output */
  129.  
  130. #ifdef S_WINCH
  131.     if (tsignals & S_WINCH)
  132.     {
  133.         int old_width, old_height;
  134.         /*
  135.          * Re-execute get_term() to read the new window size.
  136.          */
  137.         old_width = sc_width;
  138.         old_height = sc_height;
  139.         get_term();
  140.         if (sc_width != old_width || sc_height != old_height)
  141.             first_cmd = "r";
  142.         longjmp(main_loop, 1);
  143.     }
  144. #endif
  145. #ifdef SIGTSTP
  146.     if (tsignals & S_STOP)
  147.     {
  148.         /*
  149.          * Clean up the terminal.
  150.          */
  151. #ifdef SIGTTOU
  152.         SIGNAL(SIGTTOU, SIG_IGN);
  153. #endif
  154.         lower_left();
  155.         clear_eol();
  156.         flush();
  157.         raw_mode(0);
  158. #ifdef SIGTTOU
  159.         SIGNAL(SIGTTOU, SIG_DFL);
  160. #endif
  161.         SIGNAL(SIGTSTP, SIG_DFL);
  162. #if SIGSETMASK
  163.         /*
  164.          * This system will not allow us to send a 
  165.          * stop signal (SIGTSTP) to ourself
  166.          * while we are in the signal handler, like maybe now.
  167.          * (This can be the case if we are reading; see comment above.)
  168.          * So we ask the silly system for permission to do so.
  169.          */
  170.         sigsetmask(0);
  171. #endif
  172.         kill(getpid(), SIGTSTP);
  173.         /*
  174.          * ... Bye bye. ...
  175.          * Hopefully we'll be back later and resume here...
  176.          * Reset the terminal and arrange to repaint the
  177.          * screen when we get back to the main command loop.
  178.          */
  179.         SIGNAL(SIGTSTP, stop);
  180.         raw_mode(1);
  181.         first_cmd = "r";
  182.         longjmp(main_loop, 1);
  183.     }
  184. #endif
  185.     if (tsignals & S_INTERRUPT)
  186.     {
  187.         bell();
  188.         /*
  189.          * {{ You may wish to replace the bell() with 
  190.          *    error("Interrupt"); }}
  191.          */
  192.     }
  193.  
  194.     longjmp(main_loop, 1);
  195. #endif
  196. }
  197.